iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
AI & Data

Rust 加 MLOps,你說有沒有搞頭?系列 第 28

[Day 28] - 預測服務 🚀 (下) | Rust x Docker 部署鋼鐵草泥馬 🦙🦀

  • 分享至 

  • xImage
  •  

今日份 Ferris

今天要使用 Docker 把先前的專案容器化啦,畫圖的時候畫出鯨魚 (海豚?) 螃蟹,有夠可愛哈哈哈
https://ithelp.ithome.com.tw/upload/images/20231013/20141304hUxWhess6t.png

部署機器學習應用

🏮 今天要部署的專案包含最終的 Dockerfile 都可以在 GitHub 找到。

在昨天的內容中,我們談到了以 ML 系統設計的角度怎麼處理要進入產品環境的機器學習模型。
而在實作先前的專案時,其實已經依照這個思路去考量了軟、硬體的需求,包含了如何挑選與使用量化模型 ([Day 15] - 鋼鐵草泥馬 🦙 LLM chatbot 🤖 (6/10)|GGML 量化 LLaMa)。

然而,在專案的最後 [Day 19] - 鋼鐵草泥馬 🦙 LLM chatbot 🤖 (10/10)|結論及展望 只有粗略的提到部署 Rust 應用程式的過程不會很複雜。
所以今天我們就要實際走過這個流程,讓鋼鐵草泥馬 🦙 真正的飛上雲端!

🚨 這裡不會介紹 Docker 是什麼以及該怎麼操作,只會走過必要的步驟並搭配相對應的解說。
如果想完整學習 Docker 的話,推薦 Learn Docker in a Month of Lunches

docker init

要將專案變成映像檔的關鍵角色是 Dockerfile,但如果不是天天都在寫,我想八成的孩子會忘記語法。
真是拿你沒辦法,還好 Docker A 夢都幫我們準備好了 (請下 BGM~),docker init
https://ithelp.ithome.com.tw/upload/images/20231013/201413042IbwGtzAWY.png
直接在專案資料夾中執行 docker init 就可以開始生成需要的檔案:
docker init

這裡的答案分別是 Rust1.75.0-nightly3000
注意,Docker Desktop 的版本要大於 4.21 才會支援 Rust。

可以看到只需要回答幾個問題 (大部分都是自動偵測),不到 10 秒就能為專案初始化以下檔案:

  • .dockerignore
  • Dockerfile
  • compose.yaml

Dockerfile

雖然自動生成 Dockerfile 很快很方便,但我們還是需要做一些修改讓它適用於我們的專案。
fasssst

以下是修改後的 Dockerfile,每個指令的說明已經註解在上面了:

# App 名稱
ARG APP_NAME=iron_llama
# 要複製進最終映像檔的模型名稱
ARG MODEL_NAME=Taiwan-LLaMa-13b-1.0.ggmlv3.q2_K.bin

# 建置階段,使用 Rust 每夜版
FROM rustlang/rust:nightly-bookworm-slim as build
ARG APP_NAME

# 指定工作位址並將所有東西複製到容器中
WORKDIR /app
COPY . .

# 安裝需要的工具
RUN apt-get update
RUN apt-get install -y pkg-config openssl libssl-dev curl

# 加上 WASM target
RUN rustup target add wasm32-unknown-unknown

# 安裝 cargo-binstall, 這可以使安裝其它 cargo 擴充套件如 cargo-leptos 更容易
RUN wget https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz
RUN tar -xvf cargo-binstall-x86_64-unknown-linux-musl.tgz
RUN cp cargo-binstall /usr/local/cargo/bin
# 安裝 cargo-leptos
RUN cargo binstall cargo-leptos -y

# 建置 app
RUN cargo leptos build --release -vv

# 最終階段
FROM rustlang/rust:nightly-bookworm-slim as final
ARG APP_NAME
ARG MODEL_NAME

RUN apt-get update && apt-get install -y openssl

WORKDIR /app
# 把模型複製到 model
COPY --from=build /app/$MODEL_NAME model
# 把伺服器的二進制檔複製到 server 
COPY --from=build /app/target/server/release/$APP_NAME server
# 把 包含了 JS/WASM/CSS, etc. 的 /target/site 複製過來
COPY --from=build /app/target/site target/site

# 設定環境變數
ENV MODEL_PATH="/app/model"
ENV LEPTOS_SITE_ADDR="0.0.0.0:3000"

# 設定使用者
ARG UID=10001
RUN adduser \
    --disabled-password \
    --gecos "" \
    --home "/nonexistent" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    appuser

# 更改權限
RUN chown -R appuser:appuser /app
RUN chmod -R 755 /app

# 切換使用者
USER appuser

# 暴露端口
EXPOSE 3000

# 跑起來!
CMD ["/app/server"]

由於需要經歷多個階段的命令才能完成映像檔的製作,所以上面的 Dockerfile 又被稱為 多階段 Dockerfile
其中最重要的指令如下:

  • 使用 FROM 命令指定基底映像檔,並使用 AS 參數為階段命名。
  • 使用 COPY 命令搭配 --from 參數複製先前階段的檔案和目錄。
    雖然每個階段都是獨立執行,但這麼做 Docker 就知道要從先前階段而非從本機複製。

而這個 Dockerfile 的輸出為 最終階段 (final) 所產出的 Docker 映像檔!
使用多階段 Dockerfile 具有以下優點:

  • 可以使應用程式具有可移植性,Docker 讓我們能夠在任何地方的容器中執行該應用程式,甚至可以在任何作業系統底下建置該應用程式。
  • 可以減少 Docker 映像檔的大小,因為最終階段只會包含應用程式在執行階段所需的檔案。
  • 可以簡化開發人員的環境設定,因為建置工具都集中在 Docker 映像檔中。

而且再複雜的應用程式都可以使用這個流程用 Dockerfile 建置,各階段的目的整理如下:

  1. 建置階段:先安裝建置應用程式所需的工具,然後再編譯程式碼。
  2. 測試階段 (此處省略):從建置階段複製已編譯好的二進位檔進行單元測試。
  3. 最終階段:複製成功完成測試的編譯檔案。

這個 Dockerfile 唯一需要注意的就是基礎映像檔使用的是每夜版,它位於 docker hub 的 rustlang/rust,而非 docker init 所生成指向 rust 官方儲存庫rust:1.75.0-nightly-slim-bullseye (這個 tag 不存在)!

建立映像檔

建立映像檔就很簡單了,只需要執行:

docker compose up --build

就能讓應用程式跑起來!

上雲!

由於雲端平台並非這次系列文的主軸,所以這裡用最單純 (傻瓜) 的方法,把所有東西都帶上 AWS EC2 後直接 docker compose up
但這樣也可以透過 Public IPv4 DNS 的 3000 端口存取到我們的應用程式 (因為用的是算力很低的 instance 所以就不等模型回答了😴,但也代表如果使用更好的硬體也能得到更好的體驗🥳):
demo
而我們也可以把映像檔傳到 AWS ECR,來將容器部署到 AWS ECS 等服務,重點在於使用 Docker 我們可以很輕鬆的部署由 Rust 建構的應用程式,而我們可以得到所有 Rust 提供的好處。

好啦今天就到這裡囉,鐵人賽接近尾聲了,請大家欣賞一下今天畫出來的圖,明天見~
/images/emoticon/emoticon82.gif

Bonus - 今日份 Ferris 遺珠大賞

今天其實畫出不少覺得不錯的圖,精選了四張放在這裡以資尊重:
https://ithelp.ithome.com.tw/upload/images/20231013/20141304n18kso5p1K.png


上一篇
[Day 27] - 預測服務 🚀 (上) | ML 系統設計 🏭
下一篇
[Day 29] - 期末專欄 🎞️ | Rust 是資料分析的未來嗎?
系列文
Rust 加 MLOps,你說有沒有搞頭?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言